<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/1/18
 * Time: 16:42
 */
class Http
{
    //监听ip
    protected $host;
    //监听端口
    protected $port;
    //服务对象
    protected $httpServer;

    public function __construct($port = 9051, $host = '0.0.0.0')
    {
        $this->host = $host;
        $this->port = $port;
        // 实例化swoole http对象
        $this->httpServer = new \Swoole\Http\Server($this->host, $this->port);
        //设置访问静态资源文件
        $this->httpServer->set([
            // 静态资源设置路径
            'document_root' => 'G:\haibei\websocket\swoole\tp5\public\static',
            'worker_num' => 5,//设置worker进程数量不写默认是4个
            'enable_static_handler' => true,//开启静态访问
            'task_worker_num'=>5 //开启task 任务必须实现 onTask onFinish
        ]);

        //监听task worker requset 等事件前执行的事件
        $this->httpServer->on('WorkerStart', [$this, 'onWorkerStart']);
        // 监听task任务事件
        $this->httpServer->on('task', [$this, 'onTask']);
//        task 任务回调 onTask 执行完毕 回调 onFinish方法
        $this->httpServer->on('finish', [$this, 'onFinish']);
        //监听请求事件
        $this->httpServer->on('request', [$this, 'http_request']);
        // 开启服务
        $this->httpServer->start();

    }

//此事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程生命周期内使用
    public function onWorkerStart(swoole_server $server, $worker_id)
    {
//        执行requset 事件前加载tp5框架核心文件
        // 加载基础文件
        require __DIR__ . '/../thinkphp/base.php';
        think\Container::get('app')->run()->send();
    }

    //监听http请求事件
    public function http_request(Swoole_Http_Request $request, Swoole_Http_Response $response)
    {
//        $response->header('Content-Encoding','gzip');
//        $content = gzencode(11);
//        $response->gzip();
//        使用Chrome浏览器访问服务器，会产生额外的一次请求，/favicon.ico，可以在代码中响应404错误。
        if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
            return $response->end();
        }
//        注意事项
//        1 进程没有关闭框架变量没有释放
//        重写swoole的server全局变量
// 把swoole接收的信息转换为thinkphp可识别的
//        $_SERVER = [];
        if (isset($request->server)) {
            foreach ($request->server as $key => $value) {
                $_SERVER[strtoupper($key)] = $value;
            }
        }
        if (isset($request->header)) {
            foreach ($request->header as $key => $value) {
                $_SERVER[strtoupper($key)] = $value;
            }
        }
        // swoole对于超全局数组：$_SERVER、$_GET、$_POST、define不会释放
        $_GET = [];
        if (isset($request->get)) {
            foreach ($request->get as $key => $value) {
                $_GET[$key] = $value;
            }
        }
        $_POST = [];
        print_r($request->post);
        if (isset($request->post)) {
            foreach ($request->post as $key => $value) {
                $_POST[$key] = $value;
            }
        }
//        吧swooleHttp对象 赋值全局变量 tp框架中都可以使用
        $_POST['swoole_http_obj']= $this->httpServer;

//        执行tp框架
        try{
            ob_start();
            think\Container::get('app')->run()->send();
            $content = ob_get_contents();
            ob_end_clean();
        }catch (Exception $e){
            print_r($e->getMessage());
            return;
        }
        // 执行应用并响应
        //返回客户端消息
        $response->end($content);
//        $this->httpServer->reload();
    }

    /**
    /**  实现本方法必须实现onFinish事件
     * @param \swoole_http_server $server 服务对象 是http就是http对象 webscoket就是webscoket对象
     * @param $task_id int 任务id 由swoole扩展内自动生成
     * @param $src_worker_id  int 来自于哪个worker进程id
     * @param $data array 是任务的数据
     * @return string
     */
    public function onTask(swoole_http_server $server, $task_id, $src_worker_id, $data)
    {
        $method=$data['method'];
        $task = new \app\common\lib\task\Task();
        $result =$task->$method($data['data']);
        return  json_encode($result);
    }

    /**
     * @param swoole_http_server $server  服务对象 是http就是http对象 webscoket就是webscoket对象
     * @param $task_id  int 任务id 由swoole扩展内自动生成
     * @param string $data 是onTask 方法返回的数据
     */
    public function onFinish(swoole_http_server $server,  $task_id, string $data){
        print_r($data);
    }






}

$re = new Http(8080);


